24 #define foreach(x, v) for (typeof (v).begin() x=(v).begin(); x !=(v).end(); ++x)
25 #define For(i, a, b) for (int i=(a); i<(b); ++i)
26 #define D(x) cout << #x " is " << x << endl
28 const double EPS
= 1e-9;
29 int cmp(double x
, double y
= 0, double tol
= EPS
) {
30 return (x
<= y
+ tol
) ? (x
+ tol
< y
) ? -1 : 0 : 1;
34 ACRush's Dinic algorithm for maximum flow
38 init(number of nodes, source, sink);
39 Create graph using add_edge(int u, int v, int c1, int c2):
40 This adds two directed edges: u -> v with capacity c1
41 and v -> u with capacity c2.
43 After creating the graph, nedge contains the number of
46 This doesn't modify the capacity of the original graph,
47 so you can run the algorithm several times on the same
49 If you want to run the algorithm with different sources/sinks
50 assign the correct value to src and dest before calling
54 const int MAXN
= 1001;
57 const int maxnode
=MAXN
* 4 + 2;
58 const int maxedge
=2*(MAXN
* (MAXN
+ 1) + 4 * MAXN
);
59 const int oo
=1000000000;
61 int node
,src
,dest
,nedge
;
62 int head
[maxnode
],point
[maxedge
],next
[maxedge
], flow
[maxedge
], work
[maxnode
], dist
[maxnode
];
63 unsigned short capa
[maxedge
];
66 void init(int _node
,int _src
,int _dest
) {
70 for (int i
=0;i
<node
;i
++) head
[i
]=-1;
74 void add_edge(int u
,int v
,int c1
,int c2
= 0) {
75 point
[nedge
]=v
,capa
[nedge
]=c1
,flow
[nedge
]=0,
76 next
[nedge
]=head
[u
],head
[u
]=(nedge
++);
78 point
[nedge
]=u
,capa
[nedge
]=c2
,flow
[nedge
]=0,
79 next
[nedge
]=head
[v
],head
[v
]=(nedge
++);
83 memset(dist
,255,sizeof(dist
));
87 for (int cl
=0; cl
<sizeQ
; cl
++)
88 for (int k
=Q
[cl
],i
=head
[k
]; i
>=0; i
=next
[i
])
89 if (flow
[i
]<capa
[i
] && dist
[point
[i
]]<0) {
90 dist
[point
[i
]]=dist
[k
]+1;
95 int dinic_dfs(int x
,int exp
) {
96 if (x
==dest
)return exp
;
97 for (int &i
=work
[x
]; i
>=0; i
=next
[i
]) {
99 if (flow
[i
]<capa
[i
] && dist
[v
]==dist
[x
]+1 && (tmp
=dinic_dfs(v
,min(exp
,capa
[i
]-flow
[i
])))>0) {
108 for (int i
=0; i
<nedge
; ++i
) flow
[i
] = 0;
110 while (dinic_bfs()) {
111 for (int i
=0; i
<node
; i
++) work
[i
]=head
[i
];
113 int delta
=dinic_dfs(src
,oo
);
122 /////////////// Maximum flow for sparse graphs ///////////////
123 /////////////// Complexity: O(V * E^2) ///////////////
127 initialize_max_flow();
128 Create graph using add_edge(u, v, c);
129 max_flow(source, sink);
131 WARNING: The algorithm writes on the cap array. The capacity
132 is not the same after having run the algorithm. If you need
133 to run the algorithm several times on the same graph, backup
138 // const int MAXE = 1.4 * (MAXN * (MAXN + 1) + 4 * MAXN); //Maximum number of edges
139 // const int oo = INT_MAX / 4;
147 // Builds a directed edge (u, v) with capacity c.
148 // Note that actually two edges are added, the edge
149 // and its complementary edge for the backflow.
151 // int add_edge(int u, int v, int c){
152 // adj[current_edge] = v;
153 // cap[current_edge] = c;
154 // next[current_edge] = first[u];
155 // first[u] = current_edge++;
157 // adj[current_edge] = u;
158 // cap[current_edge] = 0;
159 // next[current_edge] = first[v];
160 // first[v] = current_edge++;
163 // void initialize_max_flow(){
165 // memset(next, -1, sizeof next);
166 // memset(first, -1, sizeof first);
170 // int arrived_by[MAXE];
171 // //arrived_by[i] = The last edge used to reach node i
172 // int find_augmenting_path(int src, int snk){
174 // Make a BFS to find an augmenting path from the source to
175 // the sink. Then pump flow through this path, and return
176 // the amount that was pumped.
178 // memset(arrived_by, -1, sizeof arrived_by);
181 // arrived_by[src] = -2;
182 // while (h < t && arrived_by[snk] == -1){ //BFS
184 // for (int e = first[u]; e != -1; e = next[e]){
186 // if (arrived_by[v] == -1 && cap[e] > 0){
187 // arrived_by[v] = e;
193 // if (arrived_by[snk] == -1) return 0;
197 // while (cur != src) {
198 // neck = min(neck, cap[arrived_by[cur]]);
199 // cur = adj[arrived_by[cur] ^ 1];
203 // while (cur != src){
204 // //Remove capacity from the edge used to reach node "cur"
205 // //Add capacity to the backedge
206 // cap[arrived_by[cur]] -= neck;
207 // cap[arrived_by[cur] ^ 1] += neck;
208 // //move backwards in the path
209 // cur = adj[arrived_by[cur] ^ 1];
214 // int max_flow(int src, int snk){
215 // int ans = 0, neck;
216 // while ((neck = find_augmenting_path(src, snk)) != 0){
223 const int src
= MAXN
* 4, sink
= src
+ 1;
225 int face(int number
, bool isBoy
) {
226 int ans
= isBoy
? 0 : 2 * MAXN
;
227 if (number
< 0) ans
+= -number
;
228 else ans
+= number
+ MAXN
;
230 //printf("number = %d, isBoy = %d, ans = %d\n", number, isBoy, ans);
231 assert(ans
< 4 * MAXN
);
235 unsigned short cnt
[4 * MAXN
];
241 for (int i
= 0; i
< n
; ++i
) {
242 int x
; scanf("%d", &x
);
243 assert(1500 <= abs(x
) and abs(x
) <= 2500);
244 int k
= face(x
, true);
246 //printf("cnt[boy = %d] = %d\n", x, cnt[k]);
248 for (int i
= 0; i
< n
; ++i
) {
249 int x
; scanf("%d", &x
);
250 assert(1500 <= abs(x
) and abs(x
) <= 2500);
251 int k
= face(x
, false);
253 //printf("cnt[girl = %d] = %d\n", x, cnt[k]);
256 Flow::init(Flow::maxnode
, src
, sink
);
257 //Flow::initialize_max_flow();
259 for (int boy
= -2500; boy
<= -1500; ++boy
) {
260 if (cnt
[face(boy
, true)] == 0) continue;
261 for (int girl
= 1500; girl
< -boy
; ++girl
) {
262 if (cnt
[face(girl
, false)] == 0) continue;
263 Flow::add_edge(face(boy
, true), face(girl
, false), Flow::oo
);
264 //printf("Added edge from boy = %d to girl = %d\n", boy, girl);
268 for (int boy
= 1500; boy
<= 2500; ++boy
) {
269 if (cnt
[face(boy
, true)] == 0) continue;
270 for (int girl
= -boy
-1; girl
>= -2500; --girl
) {
271 if (cnt
[face(girl
, false)] == 0) continue;
272 Flow::add_edge(face(boy
, true), face(girl
, false), Flow::oo
);
273 //printf("Added edge from boy = %d to girl = %d\n", boy, girl);
277 for (int k
= 1500; k
<= 2500; ++k
) {
278 if (cnt
[face(k
, true)] > 0) {
279 Flow::add_edge(src
, face(k
, true), cnt
[face(k
, true)]);
281 if (cnt
[face(-k
, true)] > 0) {
282 Flow::add_edge(src
, face(-k
, true), cnt
[face(-k
, true)]);
285 if (cnt
[face(k
, false)] > 0) {
286 Flow::add_edge(face(k
, false), sink
, cnt
[face(k
, false)]);
289 if (cnt
[face(-k
, false)] > 0) {
290 Flow::add_edge(face(-k
, false), sink
, cnt
[face(-k
, false)]);
294 int ans
= Flow::dinic_flow();
295 //int ans = Flow::max_flow(src, sink);